# -*- coding: utf-8 -*-
"""
信号管理器模块
提供统一的Qt信号连接生命周期管理
"""

import weakref
from typing import Dict, List, Tuple, Any, Optional, Callable
from PySide2.QtCore import QObject, Signal
from gglobal import logger


class SignalConnection:
    """信号连接信息类"""
    
    def __init__(self, signal: Signal, slot: Callable, connection_type: int = None):
        self.signal = signal
        self.slot = slot
        self.connection_type = connection_type
        self.is_connected = False
        self.connection_id = None
    
    def connect(self) -> bool:
        """建立信号连接"""
        try:
            if not self.is_connected:
                if self.connection_type is not None:
                    self.connection_id = self.signal.connect(self.slot, self.connection_type)
                else:
                    self.connection_id = self.signal.connect(self.slot)
                self.is_connected = True
                return True
        except Exception as e:
            logger.error(f"信号连接失败: {e}")
        return False
    
    def disconnect(self, *args, **kwargs) -> bool:
        """断开信号连接
        
        Args:
            *args: 接受任意位置参数（用于兼容性，会被忽略）
            **kwargs: 接受任意关键字参数（用于兼容性，会被忽略）
            
        Returns:
            bool: 断开是否成功
        """
        try:
            if self.is_connected:
                if self.connection_id is not None:
                    # 使用连接ID断开特定连接
                    self.signal.disconnect(self.connection_id)
                else:
                    # 断开到特定槽的连接
                    self.signal.disconnect(self.slot)
                self.is_connected = False
                self.connection_id = None
                return True
        except (TypeError, RuntimeError) as e:
            # 连接可能已经不存在
            logger.debug(f"信号断开时发生异常（可能已断开）: {e}")
            self.is_connected = False
            self.connection_id = None
        return False
    
    def is_valid(self) -> bool:
        """检查连接是否有效"""
        return self.is_connected and self.signal is not None and self.slot is not None


class SignalManager(QObject):
    """信号管理器基类
    
    提供统一的信号连接生命周期管理，包括：
    - 自动记录和管理信号连接
    - 防止重复连接
    - 批量断开连接
    - 连接状态监控
    """
    
    def __init__(self, parent: Optional[QObject] = None):
        super().__init__(parent)
        self._connections: Dict[str, SignalConnection] = {}
        self._connection_groups: Dict[str, List[str]] = {}
        self._auto_cleanup = True
        
        # 使用弱引用避免循环引用
        if parent:
            self._parent_ref = weakref.ref(parent)
        else:
            self._parent_ref = None
    
    def register_connection(self, 
                          connection_name: str, 
                          signal: Signal, 
                          slot: Callable, 
                          connection_type: int = None,
                          group: str = None) -> bool:
        """注册信号连接
        
        Args:
            connection_name: 连接名称（唯一标识）
            signal: Qt信号对象
            slot: 槽函数
            connection_type: 连接类型（Qt.ConnectionType）
            group: 连接组名（用于批量管理）
            
        Returns:
            bool: 注册是否成功
        """
        if connection_name in self._connections:
            logger.warning(f"信号连接 '{connection_name}' 已存在，将替换现有连接")
            self.disconnect_signal(connection_name)
        
        connection = SignalConnection(signal, slot, connection_type)
        self._connections[connection_name] = connection
        
        # 添加到组
        if group:
            if group not in self._connection_groups:
                self._connection_groups[group] = []
            self._connection_groups[group].append(connection_name)
        
        logger.debug(f"注册信号连接: {connection_name}")
        return True
    
    def connect_signal(self, connection_name: str) -> bool:
        """连接指定的信号
        
        Args:
            connection_name: 连接名称
            
        Returns:
            bool: 连接是否成功
        """
        if connection_name not in self._connections:
            logger.error(f"未找到信号连接: {connection_name}")
            return False
        
        connection = self._connections[connection_name]
        success = connection.connect()
        
        if success:
            logger.debug(f"信号连接成功: {connection_name}")
        else:
            logger.error(f"信号连接失败: {connection_name}")
        
        return success
    
    def disconnect_signal(self, connection_name: str) -> bool:
        """断开指定的信号连接
        
        Args:
            connection_name: 连接名称
            
        Returns:
            bool: 断开是否成功
        """
        if connection_name not in self._connections:
            logger.debug(f"信号连接不存在: {connection_name}")
            return False
        
        connection = self._connections[connection_name]
        success = connection.disconnect()
        
        if success:
            logger.debug(f"信号断开成功: {connection_name}")
        else:
            logger.debug(f"信号断开失败或已断开: {connection_name}")
        
        return success
    
    def connect_group(self, group_name: str) -> int:
        """连接指定组的所有信号
        
        Args:
            group_name: 组名
            
        Returns:
            int: 成功连接的信号数量
        """
        if group_name not in self._connection_groups:
            logger.warning(f"信号组不存在: {group_name}")
            return 0
        
        success_count = 0
        for connection_name in self._connection_groups[group_name]:
            if self.connect_signal(connection_name):
                success_count += 1
        
        logger.info(f"组 '{group_name}' 连接完成: {success_count}/{len(self._connection_groups[group_name])}")
        return success_count
    
    def disconnect_group(self, group_name: str) -> int:
        """断开指定组的所有信号连接
        
        Args:
            group_name: 组名
            
        Returns:
            int: 成功断开的信号数量
        """
        if group_name not in self._connection_groups:
            logger.debug(f"信号组不存在: {group_name}")
            return 0
        
        success_count = 0
        for connection_name in self._connection_groups[group_name]:
            if self.disconnect_signal(connection_name):
                success_count += 1
        
        logger.debug(f"组 '{group_name}' 断开完成: {success_count}/{len(self._connection_groups[group_name])}")
        return success_count
    
    def connect_all(self) -> int:
        """连接所有已注册的信号
        
        Returns:
            int: 成功连接的信号数量
        """
        success_count = 0
        for connection_name in self._connections:
            if self.connect_signal(connection_name):
                success_count += 1
        
        logger.info(f"批量连接完成: {success_count}/{len(self._connections)}")
        return success_count
    
    def disconnect_all(self) -> int:
        """断开所有信号连接
        
        Returns:
            int: 成功断开的信号数量
        """
        success_count = 0
        for connection_name in list(self._connections.keys()):
            if self.disconnect_signal(connection_name):
                success_count += 1
        
        logger.info(f"批量断开完成: {success_count}/{len(self._connections)}")
        return success_count
    
    def remove_connection(self, connection_name: str) -> bool:
        """移除信号连接记录
        
        Args:
            connection_name: 连接名称
            
        Returns:
            bool: 移除是否成功
        """
        if connection_name not in self._connections:
            return False
        
        # 先断开连接
        self.disconnect_signal(connection_name)
        
        # 从所有组中移除
        for group_connections in self._connection_groups.values():
            if connection_name in group_connections:
                group_connections.remove(connection_name)
        
        # 移除连接记录
        del self._connections[connection_name]
        logger.debug(f"移除信号连接: {connection_name}")
        return True
    
    def get_connection_status(self, connection_name: str) -> Optional[bool]:
        """获取连接状态
        
        Args:
            connection_name: 连接名称
            
        Returns:
            Optional[bool]: 连接状态，None表示连接不存在
        """
        if connection_name not in self._connections:
            return None
        
        return self._connections[connection_name].is_connected
    
    def get_all_connections_status(self) -> Dict[str, bool]:
        """获取所有连接的状态
        
        Returns:
            Dict[str, bool]: 连接名称到状态的映射
        """
        return {name: conn.is_connected for name, conn in self._connections.items()}
    
    def cleanup_invalid_connections(self) -> int:
        """清理无效的连接
        
        Returns:
            int: 清理的连接数量
        """
        invalid_connections = []
        
        for name, connection in self._connections.items():
            if not connection.is_valid():
                invalid_connections.append(name)
        
        for name in invalid_connections:
            self.remove_connection(name)
        
        if invalid_connections:
            logger.info(f"清理了 {len(invalid_connections)} 个无效连接")
        
        return len(invalid_connections)
    
    def set_auto_cleanup(self, enabled: bool):
        """设置是否自动清理
        
        Args:
            enabled: 是否启用自动清理
        """
        self._auto_cleanup = enabled
        logger.debug(f"自动清理设置为: {enabled}")
    
    def __del__(self):
        """析构函数，自动清理所有连接"""
        if self._auto_cleanup:
            try:
                self.disconnect_all()
                logger.debug("SignalManager 析构时自动清理完成")
            except Exception as e:
                logger.error(f"SignalManager 析构时清理失败: {e}")


class ComponentSignalManager(SignalManager):
    """组件信号管理器
    
    为特定组件提供信号管理功能的扩展类
    """
    
    def __init__(self, component_name: str, parent: Optional[QObject] = None):
        super().__init__(parent)
        self.component_name = component_name
        logger.debug(f"创建组件信号管理器: {component_name}")
    
    def setup_component_signals(self):
        """设置组件信号连接
        
        子类应重写此方法来定义具体的信号连接
        """
        pass
    
    def teardown_component_signals(self):
        """清理组件信号连接"""
        self.disconnect_all()
        logger.info(f"组件 '{self.component_name}' 信号连接已清理")
    
    def reconnect_component_signals(self):
        """重新连接组件信号"""
        self.disconnect_all()
        self.setup_component_signals()
        self.connect_all()
        logger.info(f"组件 '{self.component_name}' 信号连接已重建")


# 使用示例和工厂函数
def create_signal_manager(component_name: str = None, parent: QObject = None) -> SignalManager:
    """创建信号管理器实例
    
    Args:
        component_name: 组件名称，如果提供则创建ComponentSignalManager
        parent: 父对象
        
    Returns:
        SignalManager: 信号管理器实例
    """
    if component_name:
        return ComponentSignalManager(component_name, parent)
    else:
        return SignalManager(parent)